home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Frameworks
/
Recursive Shell 1.0.1
/
Recursive Shell ƒ
/
Main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-14
|
12KB
|
534 lines
/*****************************************************************************/
//
// Main.c
//
// Main source code for recursive shell, which is the basis for any variety
// of drag-and-drop utilities which recursively do something to entire
// folders of files and/or folders.
//
// Version 1.0
//
// Created: 13 May 1996
// Modified: 14 June 1996
//
/*****************************************************************************/
// Interfaces
#include "Main.h"
#include "GetFolder.h"
#include "DialogUtil.h"
#include "SearchFolder.h"
#include "Utility.h"
#include "DoStuff.h"
// Definitions
#define kSleep 32767
#define kGestaltMask 1L
// Globals
Boolean gDone, gRecurseDir;
// Prototypes
void main( void );
void ToolBoxInit( void );
void MenuBarInit( void );
void EventInit( void );
pascal OSErr DoOpenApp( AppleEvent theAppleEvent, AppleEvent reply, long refCon );
pascal OSErr DoOpenDoc( const AppleEvent *theAppleEvent, const AppleEvent *reply, long refCon );
pascal OSErr DoPrintDoc( AppleEvent theAppleEvent, AppleEvent reply, long refCon );
pascal OSErr DoQuitApp( AppleEvent theAppleEvent, AppleEvent reply, long refCon );
void EventLoop( void );
void DoEvent( EventRecord *eventPtr );
void HandleMouseDown( EventRecord *eventPtr );
void HandleAppleChoice( short item );
void HandleFileChoice( short item );
void SelectFolder( void );
void DoFileSelection( FSSpec selSpec );
void DoFolderSelection( FSSpec selSpec );
//
// Main
//
void main( void )
{
ToolBoxInit();
MenuBarInit();
// Check for System 7 or higher (since we use a lot of 7.x features):
if ( !SysSevenOrBetter() )
DisplayFatalError( "\pThis program requries System 7.0 or better." );
EventInit();
EventLoop();
}
/*****************************************************************************/
// Initialization Routines
/*****************************************************************************/
//
// ToolBoxInit
//
void ToolBoxInit( void )
{
InitGraf( &qd.thePort );
/* InitGraf( &thePort ); */ // This is how it's done in Think C...
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs( nil );
InitCursor();
}
//
// MenuBarInit
//
void MenuBarInit( void )
{
Handle menuBar;
MenuHandle menu;
menuBar = GetNewMBar( kBaseResID ); // load the menubar resource
if ( menuBar == nil )
DisplayFatalError( "\pERROR: could not load menu resource!" );
SetMenuBar( menuBar ); // make it the current menubar
menu = GetMHandle( mApple ); // get a handle to the apple menu
AddResMenu( menu, 'DRVR' ); // add the desk accessories to the Apple menu
DrawMenuBar(); // draw the menu bar
}
//
// EventInit
//
void EventInit( void )
{
OSErr err;
long feature;
AEEventHandlerUPP handlerUPP;
// Check Gestalt to see if AppleEvents are available:
err = Gestalt( gestaltAppleEventsAttr, &feature );
if ( err != noErr )
DisplayFatalError( "\pFATAL ERROR: Problem calling Gestalt. This program requires System 7 or higher." );
if ( !( feature & ( kGestaltMask << gestaltAppleEventsPresent ) ) )
DisplayFatalError( "\pFATAL ERROR: AppleEvents not available. This program requires System 7 or higher." );
// Install all the appropriate handlers:
handlerUPP = NewAEEventHandlerProc( DoOpenApp );
err = AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, handlerUPP, 0L, false );
if ( err != noErr )
DisplayAlert( "\pERROR: Open Application AppleEvent not available." );
handlerUPP = NewAEEventHandlerProc( DoOpenDoc );
err = AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments, handlerUPP, 0L, false );
if ( err != noErr )
DisplayAlert( "\pERROR: Open Document AppleEvent not available." );
handlerUPP = NewAEEventHandlerProc( DoPrintDoc );
err = AEInstallEventHandler( kCoreEventClass, kAEPrintDocuments, handlerUPP, 0L, false );
if (err != noErr )
DisplayAlert( "\pError: kAEPrintDocuments Apple Event not available" );
handlerUPP = NewAEEventHandlerProc( DoQuitApp );
err = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, handlerUPP, 0L, false );
if ( err != noErr )
DisplayAlert( "\pError: kAEQuitApplication Apple Event not available" );
}
/*****************************************************************************/
// Menu-managing Routines
/*****************************************************************************/
//
// WorkMenus
// The menus as shown while the program is recursing through files/folders.
// The "Open..." item is changed to "Abort" and everything else is disabled.
//
void WorkMenus( void )
{
MenuHandle myMenu;
myMenu = GetMenuHandle( mApple );
if ( myMenu != nil )
DisableItem( myMenu, iAbout );
myMenu = GetMenuHandle( mFile );
if ( myMenu != nil )
{
SetMenuItemText( myMenu, iOpen, "\pAbort" );
SetItemCmd( myMenu, iOpen, '.' );
EnableItem( myMenu, iOpen );
DisableItem( myMenu, iPrefs );
DisableItem( myMenu, iQuit );
}
myMenu = GetMenuHandle( mEdit );
if ( myMenu != nil )
{
DisableItem( myMenu, iUndo );
DisableItem( myMenu, iCut );
DisableItem( myMenu, iCopy );
DisableItem( myMenu, iPaste );
DisableItem( myMenu, iClear );
}
}
//
// WaitMenus
// The menus as shown while the program is waiting.
//
void WaitMenus( void )
{
MenuHandle myMenu;
myMenu = GetMenuHandle( mApple );
if ( myMenu != nil )
EnableItem( myMenu, iAbout );
myMenu = GetMenuHandle( mFile );
if ( myMenu != nil )
{
SetMenuItemText( myMenu, iOpen, "\pOpen..." );
SetItemCmd( myMenu, iOpen, 'O' );
EnableItem( myMenu, mFile );
DisableItem( myMenu, iPrefs ); // Preferences not implemented yet
EnableItem( myMenu, iQuit );
}
myMenu = GetMenuHandle( mEdit );
if ( myMenu != nil )
{
DisableItem( myMenu, iUndo );
DisableItem( myMenu, iCut );
DisableItem( myMenu, iCopy );
DisableItem( myMenu, iPaste );
DisableItem( myMenu, iClear );
}
}
/*****************************************************************************/
// AppleEvent-handling Routines
/*****************************************************************************/
//
// DoOpenApp
//
pascal OSErr DoOpenApp( AppleEvent theAppleEvent, AppleEvent reply, long refCon )
{
// This handler gets called when the user double-clicks on the icon.
// It does not get called when the user drops something on the icon.
ShowAboutBox();
return ( noErr );
}
//
// DoOpenDoc
//
pascal OSErr DoOpenDoc( const AppleEvent *theAppleEvent, const AppleEvent *reply, long refCon )
{
OSErr err;
AEDescList docList;
long count, index;
AEKeyword keyword;
DescType type;
FSSpec file;
Size actualSize;
InitializeStuff();
err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList);
if ( err == noErr )
{
if ( AECountItems( &docList, &count ) == noErr )
{
WorkMenus(); // Disable most stuff in menus.
for ( index = 1; index <= count; index++ )
{
if ( AEGetNthPtr( &docList, index, typeFSS, &keyword, &type,
&file, sizeof( file ), &actualSize ) == noErr )
{
// A little bit of disturbing news. If the user drops an alias on my
// icon, 'file' refers to the TARGET file - the Finder resolves the alias
// automatically. From what I can tell, there's no way for me to
// determine if what was dropped on me was really an alias.
if ( IsAFolder( &file ) ) // it is a folder
DoFolderSelection( file );
else // it is a file
DoFileSelection( file );
}
else
DisplayAlert( "\pERROR: Could not get AppleEvent data." );
}
WaitMenus(); // Set menus back to normal.
}
else
{
err = AEDisposeDesc( &docList );
DisplayFatalError( "\pFATAL ERROR: Could not get AppleEvents data." );
}
}
else
DisplayFatalError( "\pFATAL ERROR: Could not get AppleEvents data." );
DeInitializeStuff();
gDone = true; // quit when we're done
return ( noErr );
}
//
// DoPrintDoc
//
pascal OSErr DoPrintDoc( AppleEvent theAppleEvent, AppleEvent reply, long refCon )
{
return errAEEventNotHandled;
}
//
// DoQuitApp
//
pascal OSErr DoQuitApp( AppleEvent theAppleEvent, AppleEvent reply, long refCon )
{
gDone = true;
return ( noErr );
}
/*****************************************************************************/
// Event-handling Routines
/*****************************************************************************/
//
// EventLoop
//
void EventLoop( void )
{
EventRecord event;
gDone = false;
gRecurseDir = true; // This should be stored in preferences file, actually
while (gDone == false )
{
if (WaitNextEvent( everyEvent, &event, kSleep, nil ) )
DoEvent( &event );
}
}
//
// DoEvent
//
void DoEvent( EventRecord *eventPtr )
{
char theChar;
switch ( eventPtr->what )
{
case kHighLevelEvent:
AEProcessAppleEvent( eventPtr );
break;
case mouseDown:
HandleMouseDown( eventPtr );
break;
case keyDown:
case autoKey:
theChar = eventPtr->message & charCodeMask;
if ( (eventPtr->modifiers & cmdKey) != 0)
HandleMenuChoice( MenuKey( theChar ) );
break;
}
}
//
// HandleMouseDown
//
void HandleMouseDown( EventRecord *eventPtr )
{
WindowPtr window;
short thePart;
long menuChoice;
thePart = FindWindow( eventPtr->where, &window );
switch ( thePart )
{
case inMenuBar:
menuChoice = MenuSelect( eventPtr->where ); // do the menu thing
HandleMenuChoice( menuChoice );
break;
case inSysWindow:
SystemClick( eventPtr, window );
break;
}
}
//
// HandleMenuChoice
//
void HandleMenuChoice( long menuChoice )
{
short menu;
short item;
if ( menuChoice != 0 )
{
menu = HiWord( menuChoice );
item = LoWord( menuChoice );
switch ( menu )
{
case mApple:
HandleAppleChoice( item );
break;
case mFile:
HandleFileChoice( item );
break;
case mEdit:
// Edit menu is there only for the sake of DAs...
break;
}
HiliteMenu( 0 );
}
}
//
// HandleAppleChoice
//
void HandleAppleChoice( short item )
{
MenuHandle appleMenu;
Str255 accName;
short accNumber;
switch ( item )
{
case iAbout:
ShowAboutBox();
break;
default:
appleMenu = GetMHandle( mApple );
GetItem( appleMenu, item, accName );
accNumber = OpenDeskAcc( accName );
break;
}
}
//
// HandleFileChoice
//
void HandleFileChoice( short item )
{
switch ( item )
{
case iOpen:
SelectFolder(); // Do the open file stuff...
break;
case iPrefs:
// The preferences stuff is currently unimplemented...
break;
case iQuit:
gDone = true;
break;
}
}
void SelectFolder( void )
{
StandardFileReply reply;
OSErr err;
Str255 returnValue;
err = CustomGetFolder( &reply );
if ( err == noErr )
{
if ( reply.sfGood ) // User did not hit cancel.
{
WorkMenus(); // Disable most stuff in menus.
if ( InitializeStuff() )
{
if ( IsAFolder( &(reply.sfFile) ) )
DoFolderSelection( reply.sfFile );
else
DoFileSelection( reply.sfFile );
DeInitializeStuff();
}
WaitMenus(); // Set menus back to normal.
}
}
else
{
ResolveOSErr( err, returnValue );
DisplayAlert( returnValue );
}
}
//
// DoFileSelection
//
void DoFileSelection( FSSpec selSpec )
{
BusyCursor(); // Set the cursor to the watch.
DoToEachFile( selSpec );
SetCursor( &qd.arrow ); // Set the cursor back to the arrow
}
//
// DoFolderSelection
//
void DoFolderSelection( FSSpec selSpec )
{
BusyCursor(); // Set the cursor to the watch.
DoAllFiles( selSpec ); // Do the recursive stuff.
DoToSelFolder( selSpec );
SetCursor( &qd.arrow ); // Set the cursor back to the arrow
}